<template>
  <div>
    <textarea :id="editRef" placeholder="请输入..."></textarea>
  </div>
</template>

<script>
import Uuid from "uuid";
import buildConfig from "../../../build/config";
import request from "@/utils/request";
import config from "@/utils/config";
import appService from "@/utils/appService";

/** 当前环境 */
const currentEnv = buildConfig.currentEnv;
/** 当前配置 */
const currentConfig = buildConfig[currentEnv];
let publicPath = "";
if (currentEnv !== "development") {
  let serverPath = currentConfig.serverPath;
  if (!serverPath.endsWith("/")) {
    serverPath += "/";
  }
  let uiApi = currentConfig.uiApi;
  if (uiApi.startsWith("/")) {
    uiApi = uiApi.substring(1, uiApi.length);
  }
  if (uiApi.length !== 0) {
    if (!uiApi.endsWith("/")) {
      uiApi += "/";
    }
  }
  /** 静态资源按需引入的publicPath，如果错误，请求会出现404 */
  publicPath = serverPath + uiApi;
}

export default {
  props: {
    value: {
      type: String
    }
  },
  model: {
    prop: "value",
    event: ["onChange"]
  },
  data: function() {
    return {
      editRef: Uuid.v1()
    };
  },
  mounted: function() {
    let script = document.createElement("script");
    script.type = "text/javascript";
    script.src = `${publicPath}/static/tinymce/tinymce.min.js`;
    document.body.appendChild(script);
    let vm = this;
    script.onload = function() {
      let tinyMCE = window.tinyMCE;
      tinyMCE.init({
        /** 表单控件.样式名称 - 绑定textarea */
        selector: `#${vm.editRef}`,
        /** 高度 */
        height: "500",
        /** 宽度 */
        width: null,
        /** 控件大小 */
        toolbar_items_size: "small",
        /** 是否显示工具栏 */
        toolbar: true,
        toolbar1:
          "undo redo | cut copy paste | bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | styleselect formatselect fontselect fontsizeselect",
        toolbar2_back:
          " searchreplace | bullist numlist | outdent indent blockquote | link unlink anchor image media code | inserttime preview | forecolor backcolor",
        toolbar3_back:
          "table | hr removeformat | subscript superscript | charmap emoticons | print fullscreen | ltr rtl | spellchecker | visualchars visualblocks nonbreaking template pagebreak restoredraft",
        /** 是否显示菜单栏 */
        menubar: true,
        language: "zh_CN",
        /** 插件区，激活控件 */
        plugins: [
          "advlist autolink autosave link image lists charmap print preview hr anchor pagebreak spellchecker",
          "searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking",
          "table contextmenu directionality emoticons template textcolor paste fullpage textcolor"
        ],
        /** 选中时出现的快捷工具，与插件有依赖关系 */
        quickbars_selection_toolbar:
          "bold italic forecolor | link blockquote quickimage",
        /** 是否开启内联模式，内联模式最大的好处，是内容完全继承自外层定义的样式，真正实现了"所见即所得"。但要注意，请小心使用杀伤力比较大的自定义CSS，因为这样可能会覆盖TinyMCE控件的CSS，导致编辑器显示异常 */
        inline: false,
        /** 使用空格或逗号分隔，允许的值包括：file,image和media。该选项需配合file_picker_types使用，未指定的对话框则不会出现文件上传按钮。file对应链接对话框，image对应图片对话框，media对应多媒体对话框。 */
        file_picker_types: "file image media",
        images_upload_handler: vm.handleImageUpload,
        file_picker_callback: vm.handleFileUpload,
        setup: function(editor) {
          vm.editor = editor;
          editor.on("change", vm.handleContentChange);
        }
      });
    };
  },
  computed: {},
  watch: {
    value: function(newValue, oldValue) {
      if (this.editor) {
        this.editor.setContent(newValue);
      }
    }
  },
  methods: {
    getUploadTicket: async function() {
      /** http://tgw.wiiqq.com/test/api/cos/ticket/get_ticket?bucket=manager */
      /** https://gw.ybsjyyn.com/api/cos/ticket/get_ticket?bucket=manager */
      let responst = await appService.getRequest(
        "https://gw.ybsjyyn.com/api/cos/ticket/get_ticket?bucket=manager"
      );
      let ticket = responst.data.data.ticket;
      return ticket;
    },
    /** @param callback：上传成功后执行的回调函数，此函数是由TinyMCE定义的，它的第一个参数是上传结果，第二个参数可以是一个object，其中定义了要填入对话框中的字段键值。
     * @param value：当前受影响的字段值
     * @param meta：为一个包含指定对话框中其它字段值的对象（meta.filetype是当前对话框的文件类型）
     */
    handleFileUpload: async function(callback, value, meta) {
      let vm = this;
      if (meta.filetype == "media") {
        let input = document.createElement("input");
        input.setAttribute("type", "file");
        input.onchange = async function(e) {
          let uploadFile = e.target.files[0];
          let filename = uploadFile.name;
          filename = filename.substring(
            filename.lastIndexOf("."),
            filename.length
          );
          filename = Uuid.v1() + filename;
          let formData = new FormData();
          formData.append("fileContent", uploadFile);
          formData.append("op", "upload");
          formData.append("insertOnly", 0);
          /** 失败重试10次 */
          for (let i = 0; i < 10; i++) {
            let ticket = await vm.getUploadTicket();
            let uploadUrl = config.uploadApiProxy + "/" + filename;
            uploadUrl += `?sign=${ticket}`;
            let response = await request.postRequest(uploadUrl, formData, {
              onUploadProgress: progressEvent => {
                let percent =
                  (progressEvent.loaded / progressEvent.total) * 100;
                if (percent < 100) {
                  /** 是否显示loading状态：1（显示）0（隐藏） */
                  vm.editor.setProgressState(true);
                } else {
                  vm.editor.setProgressState(false);
                }
              }
            });
            if (response.status === 200) {
              let sourceUrl = response.data.data.source_url;
              callback(sourceUrl, { title: uploadFile.name });
              break;
            }
            if (i === 9) {
              let status = response.status;
              let message = "";
              if (response.data instanceof Object) {
                message = response.data.message;
              }
            }
          }
        };
        input.click();
      }
    },
    handleImageUpload: async function(blobInfo, success, failure) {
      let filename = blobInfo.filename();
      filename = filename.substring(filename.lastIndexOf("."), filename.length);
      filename = Uuid.v1() + filename;
      let blob = blobInfo.blob();
      let formData = new FormData();
      formData.append("fileContent", blob);
      formData.append("op", "upload");
      formData.append("insertOnly", 0);
      /** 失败重试10次 */
      for (let i = 0; i < 10; i++) {
        let ticket = await this.getUploadTicket();
        let uploadUrl = config.uploadApiProxy + "/" + filename;
        uploadUrl += `?sign=${ticket}`;
        let response = await request.postRequest(uploadUrl, formData);
        if (response.status === 200) {
          let sourceUrl = response.data.data.source_url;
          success(sourceUrl);
          break;
        }
        if (i === 9) {
          let status = response.status;
          let message = "";
          if (response.data instanceof Object) {
            message = response.data.message;
          }
          failure(status + ":" + message);
        }
      }
    },
    handleContentChange(e) {
      /** 获取html内容 */
      let htmlContent = this.editor.getContent();
      /** 获取不带HTML标记的纯文本内容 */
      //let testContent = editor.getContent({ format: "raw" });
      /** 设置内容 */
      //editor.setContent('需要设置的编辑器内容');
      this.$emit("onChange", htmlContent);
    }
  }
};
</script>

<style lang="less">
.mce-btn {
  border-radius: 4px !important;
}
.mce-textbox {
  border-radius: 4px !important;
}
.mce-statusbar {
  display: none !important;
}
</style>

